﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SoftwareConsulting.BI11.NumericalMethods.LinearEquationsSystems
{
    /// <summary>
    /// Класс метода Зейделя для решения СЛАУ
    /// </summary>
    public class ZeidelMethod
    {
        private const double _eps = 0.0001f;
        private double[] _result;

        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="n">Число уравнений в системе</param>        
        public ZeidelMethod(int n, double[,] A,double[] B)
        {
            _result = new double[n];           
            int[] res1 = new int[n];
            double[] X = new double[n];            
            for (int i = 0; i < n; i++)
            {
                X[i] = 0;
            }
            if (CalculateZeidelMethod(A, B, X, _eps, n) == 1)
            {
                for (int i = 0; i < n; i++)
                {
                    _result[i] = X[i];
                }
            }
        }

        /// <summary>
        /// Вычисляет по методу Зейделя
        /// </summary>        
        public int CalculateZeidelMethod(double[,] a, double[] b, double[] x, double epsilon, int n)
        {
            int i = 0;
            int j = 0;
            double s1 = 0;
            double s2 = 0;
            double v = 0;
            double m = 0;
            do
            {
                m = 0;
                for (i = 0; i < n; i++)
                {
                    s1 = 0;
                    s2 = 0;
                    for (j = 0; j < i; j++) s1 += a[i, j] * x[j];
                    for (j = i; j < n; j++) s2 += a[i, j] * x[j];
                    v = x[i];
                    x[i] -= (1 / a[i, i]) * (s1 + s2 - b[i]);
                    if ((v - x[i]) > m)
                        m = (v - x[i]);
                }
            }
            while (m >= epsilon);
            return 1;
        }

        /// <summary>
        /// Возвращает решение
        /// </summary>        
        public double[] GetSolution()
        {
            return _result;
        }
    }
}
